/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package wf3.core.cnt;

import wf.dto.geocon.GeocapDto;
import wf.dto.geocon.GeocapvalDto;
import wf.dto.geocon.GeoconDto;
import wf.dto.geocon.GeopuncapDto;
import wf.dto.geocon.Pblispuncon;
import wf.dto.qbfrawor_id_frawor;

import acceso.util.WorkflowUtil;
import wf3.gps.Agrupamiento;
import wf3.gps.Escenario;
import wf3.gps.Filtro;
import wf3.gps.Portafolio;
import wf3.gps.PunConfig;
import wf3.gps.Punto;
import acceso.hibernate.AQuery;

import acceso.util.GpsUtil;
import com.google.gson.Gson;
import java.io.FileInputStream;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.hibernate.HibernateException;
import org.hibernate.StatelessSession;
import wf.dto.ContenedorDto;
import wf3.core.ContenException;
import wf3.core.Contenedor;
import wf3.core.ManagerServlet;
import wf3.core.ManagerTransa;
import wf3.core.dao.ContenedorDAO;
import wf3.core.dao.GContenedorDAO;

/**
 *
 * @author romulogalindo
 */
public class GConten extends Contenedor implements Serializable {

    private int co_geocon;//código de geoconten
    private String ti_geovis;
    private short nu_geoace;
    private String no_geocon;
    private List<Punto> l_puntos;
    private List<Filtro> l_filtro;
    private Escenario escenario_mostrar;
    private List<Escenario> l_escenarios;
    private Portafolio portafolio;
    private boolean ocultarVacios = true;
    private boolean modoEdicion = false;
    private int co_portaf;
    private GContenedorDAO DAO;
    private GeoconDto cnt = null;

    /**
     *
     * @param manager
     * @throws ContenException
     * @throws HibernateException
     */
    public GConten(ManagerServlet manager) throws ContenException, HibernateException {
        super(manager);
        //INTANCIA DEL DATA ACCESS OBJECT
        DAO = new GContenedorDAO(manager.getUser());

        //GENERA EL NUEVO ID DE TRANSACCION:: ID_SESSION seria un atributo del objeto de usuario
        this.ID_TRANSA = DAO.NEW_IDTRANSA(manager.getRequest().getRemoteHost(), manager.getUser().getId(), WorkflowUtil.convertir_fecha(manager.get_Parameter("fe_solini"), null));

        //Conseguir el valor del parametro del geocontenedor(co_geocon);
        this.co_geocon = manager.get_Parameter_like_int("co_geocon");

        //Generarndo ID_FRAWOR (SI NO EXISTE ERROR)
        this.ID_FRAWOR = DAO.NEW_IDFRAWOR();

        //recuperando ID_FRAANT DEFAULT(0)
        this.ID_FRAANT = manager.get_Parameter_like_int("id_fraant");

        //CONJUGANDO ID_FRAWOR | ID_FRAANT | ID_SESSION | CO_CONTEN 
        DAO.INNER_SESSION(manager.getUser().getId(), this.ID_FRAWOR, this.ID_FRAANT, this.co_geocon);

        //CONSIGUIENDO OBJETO DTO
        new Thread(
                new Runnable() {
            @Override
            public void run() {
                ManagerTransa.transacon_ini(ID_TRANSA, ID_FRAWOR, co_geocon);
            }
        }).start();
        cnt = DAO.GET_CONTENDOR(this.co_geocon);
        
        this.ti_geovis = cnt.getTi_geovis();
        this.nu_geoace = cnt.getNu_geoace();
        this.no_geocon = cnt.getNo_geocon();

        //CONSIGUIENDO LA LISTA COMPLETA DE PUNTOS
        this.l_puntos = convertir_pblispun_to_puntos(DAO.GET_LIST_POINTS(this.co_geocon));
        
        //INICIALIZANDO LA LISTA DE FILTROS
        this.l_filtro = new ArrayList<>();
        
        //INICIALIZANDO LA LISTA DE ESCENARIOS
        this.l_escenarios = new ArrayList<>();
        
        List<GeocapDto> filter_list = DAO.GET_LIST_FILTERS(this.co_geocon);
        for (GeocapDto filter : filter_list) {
            Filtro filtro = new Filtro(filter);
            List<GeocapvalDto> group_list = DAO.GET_LIST_GROUPS(this.co_geocon, filter.getId().getNu_geocap());
            for (GeocapvalDto group : group_list) {
                filtro.add_agrupamient(new Agrupamiento(group, convertirListaPunConfig( DAO.GET_LIST_POINTS_FOR_GROUPS(co_geocon, filter.getId().getNu_geocap(), group.getId().getNu_geocapval()) ) ));
            }
            this.l_filtro.add(filtro);
        }
        escenario_mostrar = new Escenario(this.l_filtro.subList(0, this.l_filtro.size()-1));
        this.l_escenarios.add(escenario_mostrar);
    }

    public GConten(HttpServletRequest request, StatelessSession hibernateSession) throws ContenException, HibernateException, IOException, ClassNotFoundException {
        super(request, hibernateSession);
        this.co_geocon = WorkflowUtil.convertir_entero(request.getParameter("co_geocon"), 0);
        if (this.co_geocon == 0) {
            throw new ContenException("Contendor no valido");
        }

        //GENERACION DEl ID_FRAWOR 
        AQuery IHQUERY = new AQuery(hibernateSession.getNamedQuery("frawor2.qbfrawor_id_frawor"));
        IHQUERY.setString("frawor", "fratra.qbfrawor_id_frawor");
        qbfrawor_id_frawor qbfrawor = (qbfrawor_id_frawor) IHQUERY.getMquery2(WorkflowUtil.LOG_TRANSA).uniqueResult();

        this.ID_FRAWOR = WorkflowUtil.convertir_entero(qbfrawor.getNextval());

        this.co_portaf = WorkflowUtil.convertir_entero(request.getParameter("co_portaf"), 0);

//        if(this.co_portaf != 0){
        if (false) {
            //obtener de BD

            //deserializar el objeto
            ObjectInputStream entrada = new ObjectInputStream(new FileInputStream("/home/john/Desktop/media.gps"));
            GConten geocon = (GConten) entrada.readObject();
            entrada.close();

            System.out.println("GConten: " + geocon);
            this.ti_geovis = geocon.getTi_geovis();
            this.nu_geoace = geocon.getNu_geoace();
            this.no_geocon = geocon.getNo_geocon();
            this.l_puntos = geocon.getL_puntos();
            this.l_filtro = geocon.getL_filtro();

            this.escenario_mostrar = geocon.getEscenario_mostrar();
            this.l_escenarios = geocon.getL_escenarios();
            this.portafolio = geocon.getPortafolio();
            this.ocultarVacios = geocon.isOcultarVacios();
            this.modoEdicion = geocon.isModoEdicion();

        } else {

            IHQUERY = new AQuery(hibernateSession.getNamedQuery("frageo.pbgeocon"));
            IHQUERY.setInteger("p_co_geocon", co_geocon);
            GeoconDto geoconten = (GeoconDto) IHQUERY.getMquery2(WorkflowUtil.LOG_TRANSA).uniqueResult();

            if (geoconten != null) {
                this.ti_geovis = geoconten.getTi_geovis();
                this.nu_geoace = geoconten.getNu_geoace();
                this.no_geocon = geoconten.getNo_geocon();
                this.l_filtro = new ArrayList<>();

                //OBTENIENDO LISTA DE PUNTOS
                IHQUERY = new AQuery(hibernateSession.getNamedQuery("frageo.pblispuncon"));
                IHQUERY.setInteger("p_co_geocon", co_geocon);
                List l_puntos_dto = IHQUERY.getMquery2(WorkflowUtil.LOG_TRANSA).list();
                this.l_puntos = convertirListaPuntos(l_puntos_dto);

                //OBTENIENDO LISTA DE FILTROS
                IHQUERY = new AQuery(hibernateSession.getNamedQuery("frageo.pbgeocap"));
                IHQUERY.setInteger("p_co_geocon", co_geocon);
                List l_filtro_dto = IHQUERY.getMquery2(WorkflowUtil.LOG_TRANSA).list();

                for (int i = 0; i < l_filtro_dto.size(); i++) {
                    Filtro filtro = new Filtro();
                    GeocapDto geocap = (GeocapDto) l_filtro_dto.get(i);

                    filtro.setNo_geocap(geocap.getNo_geocap());
                    filtro.setNu_geocap(geocap.getId().getNu_geocap());

                    List<Agrupamiento> agrupamientos = new ArrayList<>();
                    //OBTENIENDO LAS AGRUPACIONES DE CADA FILTRO
                    IHQUERY = new AQuery(hibernateSession.getNamedQuery("frageo.pbgeocapval"));
                    IHQUERY.setInteger("p_co_geocon", co_geocon);
                    IHQUERY.setInteger("p_nu_geocap", geocap.getId().getNu_geocap());
                    List l_capval_dto = IHQUERY.getMquery2(WorkflowUtil.LOG_TRANSA).list();

                    for (int j = 0; j < l_capval_dto.size(); j++) {
                        Agrupamiento agrupamiento = new Agrupamiento();
//                        List<PunConfig> puntos_config = new ArrayList<>();
                        GeocapvalDto geocapval = (GeocapvalDto) l_capval_dto.get(j);

                        agrupamiento.setNo_agrupa(geocapval.getNo_geocapval());
                        agrupamiento.setNu_geocapval(geocapval.getId().getNu_geocapval());
                        agrupamiento.setTi_puncol(geocapval.getTi_puncol());

                        //OBTENIENDO LOS PUNTOS A COFIGURAR DE CADA AGRUPACION
                        IHQUERY = new AQuery(hibernateSession.getNamedQuery("frageo.pbgeopuncap"));
                        IHQUERY.setInteger("p_co_geocon", co_geocon);
                        IHQUERY.setInteger("p_nu_geocap", geocap.getId().getNu_geocap());
                        IHQUERY.setInteger("p_nu_capval", geocapval.getId().getNu_geocapval());
                        List l_puncap_dto = IHQUERY.getMquery2(WorkflowUtil.LOG_TRANSA).list();

                        agrupamiento.setL_config(convertirListaPunConfig(l_puncap_dto));
                        agrupamientos.add(agrupamiento);
                    }

                    filtro.setL_agrupa(agrupamientos);
                    this.l_filtro.add(filtro);
                }
                escenario_mostrar = new Escenario(GpsUtil.clonarFiltros(this.l_filtro));
                this.l_escenarios = new ArrayList<>();
                this.l_escenarios.add(escenario_mostrar);
                this.ocultarVacios = true;
                this.modoEdicion = false;
            }
        }
    }

    @Override
    public int get_Id_frawor() {
        return this.ID_FRAWOR;
    }

    public int getCo_geocon() {
        return co_geocon;
    }

    public void setCo_geocon(int co_geocon) {
        this.co_geocon = co_geocon;
    }

    public String getTi_geovis() {
        return ti_geovis;
    }

    public void setTi_geovis(String ti_geovis) {
        this.ti_geovis = ti_geovis;
    }

    public short getNu_geoace() {
        return nu_geoace;
    }

    public void setNu_geoace(short nu_geoace) {
        this.nu_geoace = nu_geoace;
    }

    public String getNo_geocon() {
        return no_geocon;
    }

    public void setNo_geocon(String no_geocon) {
        this.no_geocon = no_geocon;
    }

    public List<Punto> getL_puntos() {
        return l_puntos;
    }

    public void setL_puntos(List<Punto> l_puntos) {
        this.l_puntos = l_puntos;
    }

    public List<Filtro> getL_filtro() {
        return l_filtro;
    }

    public void setL_filtro(List<Filtro> l_filtro) {
        this.l_filtro = l_filtro;
    }

    public Escenario getEscenario_mostrar() {
        return escenario_mostrar;
    }

    public void setEscenario_mostrar(Escenario escenario_mostrar) {
        this.escenario_mostrar = escenario_mostrar;
    }

    public List<Escenario> getL_escenarios() {
        return l_escenarios;
    }

    public void setL_escenarios(List<Escenario> l_escenarios) {
        this.l_escenarios = l_escenarios;
    }

    public Portafolio getPortafolio() {
        return portafolio;
    }

    public void setPortafolio(Portafolio portafolio) {
        this.portafolio = portafolio;
    }

    public boolean isOcultarVacios() {
        return ocultarVacios;
    }

    public void setOcultarVacios(boolean ocultarVacios) {
        this.ocultarVacios = ocultarVacios;
    }

    public boolean isModoEdicion() {
        return modoEdicion;
    }

    public void setModoEdicion(boolean modoEdicion) {
        this.modoEdicion = modoEdicion;
    }

    public int getCo_portaf() {
        return co_portaf;
    }

    public void setCo_portaf(int co_portaf) {
        this.co_portaf = co_portaf;
    }

    private List<PunConfig> convertirListaPunConfig(List<GeopuncapDto>l_puncap) {
        List<PunConfig> punconfig = new ArrayList<>();
//        for (int i = 0; i < l_puncap.size(); i++) {
//            GeopuncapDto puncap = (GeopuncapDto) l_puncap.get(i);
//            PunConfig pc = new PunConfig(puncap.getId().getId_pungeo(), puncap.getNo_pundes(), puncap.getNo_punlab());
//            punconfig.add(pc);
//        }
        for (GeopuncapDto puncap :  l_puncap) {
//            GeopuncapDto puncap = (GeopuncapDto) l_puncap.get(i);
            PunConfig pc = new PunConfig(puncap.getId().getId_pungeo(), puncap.getNo_pundes(), puncap.getNo_punlab());
            punconfig.add(pc);
        }
        return punconfig;
    }


    private List<Punto> convertirListaPuntos(List l_puntos) {
        List<Punto> puntos = new ArrayList<>();
        for (int i = 0; i < l_puntos.size(); i++) {
            Pblispuncon p = (Pblispuncon) l_puntos.get(i);
            Punto punto = new Punto(p.getId_pungeo(), p.getNu_geolat(), p.getNu_geolon());
            puntos.add(punto);
        }
        return puntos;
    }

    private List<Punto> convertir_pblispun_to_puntos(List<Pblispuncon> l_puntos) {
        List<Punto> puntos = new ArrayList<>();
        for (Pblispuncon point :l_puntos) {
            puntos.add(new Punto(point.getId_pungeo(), point.getNu_geolat(), point.getNu_geolon()));
        }
        return puntos;
    }

    public void filtrar() {
        escenario_mostrar.filtrar();
        escenario_mostrar = escenario_mostrar.getEscenario_sig();
        l_escenarios.add(escenario_mostrar);
    }

    public void eliminarFiltro(int nu_geocap) {
        boolean eliminar = false;
        Iterator<Escenario> escenarios = l_escenarios.iterator();
        while (escenarios.hasNext()) {
            Escenario esc = escenarios.next();
            if (eliminar) {
                escenarios.remove();
            } else if (esc.getFiltro_selec().getNu_geocap() == nu_geocap) {
                esc.setEscenario_sig(null);
                escenario_mostrar = esc;
                eliminar = true;
            }

        }
    }

    public void editarFiltro(int nu_geocap) {
        for (Escenario e : l_escenarios) {
            if (e.getFiltro_selec().getNu_geocap() == nu_geocap) {
                escenario_mostrar = e;
            }
        }
        modoEdicion = true;
    }

    public void terminarEdicion() {
        escenario_mostrar = l_escenarios.get(l_escenarios.size() - 1);
        modoEdicion = false;
    }

    public void crearPortafolio() {
        portafolio = new Portafolio(GpsUtil.clonarFiltros(l_filtro), escenario_mostrar.getL_puntos_mostrados(), escenario_mostrar);
    }

    public void crearPortafolio(String l_nu_geopun) {
        List<PunConfig> l_puntos = obtenerPunconfigsPorId(l_nu_geopun.split("_"));
        portafolio = new Portafolio(GpsUtil.clonarFiltros(l_filtro), l_puntos, escenario_mostrar);
    }

    public void eliminarPortafolio() {
        portafolio = null;
    }

    public String jsonPuntos() {
        Gson g = new Gson();
        return g.toJson(l_puntos);
    }

    private List<PunConfig> obtenerPunconfigsPorId(String[] ids) {
        List<PunConfig> l_puntos = new ArrayList<>();
        for (int i = 0; i < ids.length; i++) {
            for (PunConfig p : escenario_mostrar.getL_puntos_mostrados()) {
                if (Integer.parseInt(ids[i]) == p.getId_pungeo()) {
                    l_puntos.add(new PunConfig(p.getId_pungeo(), p.getNo_pundes(), p.getNo_punlab()));
                }
            }
        }
        return l_puntos;
    }

    @Override
    public int get_Co_conten() {
        return 0;
    }

    @Override
    public String get_No_conten() {
        return cnt.getNo_geocon();
    }
    
    @Override
    public String get_No_type() {
        return "gconten";
    }
}